
package com.ys.chatserver.http.logic;

import com.ys.chatserver.common.dto.cnst.UserProtocalsType;
import com.ys.chatserver.http.logic.dto.JobDispatchConst;
import com.ys.chatserver.im.impl.ChatLogicManager;
import net.ys.mobileimsdk.server.processor.OnlineProcessor;
import net.ys.mobileimsdk.server.protocal.Protocal;
import net.ys.mobileimsdk.server.protocal.ProtocalFactory;

import com.alibaba.fastjson.JSONObject;
import com.eva.epc.common.util.CommonUtils;
import com.eva.framework.Processor;
import com.eva.framework.dbpool.DBShell;
import com.eva.framework.dto.SysActionConst;
import com.eva.framework.utils.EndsExceptionFactory;
import com.eva.framework.utils.LoggerFactory;

/**
 * 服务端对外提供的实时消息推送等特权接口处理器。
 * <p>
 * 此处理器内的接口均为用于管理端的特权接口，原则上客户端禁止调用。
 * 
 * @version 1.0
 * @since 4.0
 */
public class IMAdminProcessor implements SysActionConst, Processor
{
	public static DBShell db = new DBShell();
	
	/**
	 * 处理器的核心实现方法.<br>
	 * 可据job_dispatch_id找到对应的JobDispatcher，JobDispatcher又能据
	 * action_id进行对应动作的处理，以完成本次操作请求.
	 * 
	 * @param job_dispatch_id 作业调度ID
	 * @param action_id 动作ID
	 * @return 任意类型返回值
	 */
	@Override public Object process(int job_dispatch_id, int action_id, Object _newData, Object _oldData, User user)
			throws Exception
	{
		Object ret = null;
		String newDataJSON = (String)_newData;

        // 处理服务端对外提供的实时消息推送接口的管理
        if (job_dispatch_id == JobDispatchConst.LOGIC_MSG$PUSH) {
            ret = maintainMgrMsg$PushJobDispatcher(action_id, newDataJSON, _oldData, user);
        } else {
            throw EndsExceptionFactory.INVALID_JOB_DISPATCHER_ID(job_dispatch_id);
        }
		return ret;
	}
	
	/** 
	 * 维护服务端对外提供的实时消息推送接口的管理.
	 * 
	 * @param action_id 维护类型，SysConstant中的操作类型常量
	 * @param oldData 客端发送过来的本次修改前的老数据(可能为空，理论上与newData不会同时空）
	 * @return 返回给客户端的对象
	 */
	public Object maintainMgrMsg$PushJobDispatcher(int action_id
			, String newDataJSON, Object oldData, User user) throws Exception
	{
        // 向指定客户端推送一条消息或指令（目前暂时用作网页管理端调用，请注意安全性）
        if (action_id == ACTION_APPEND1) {// 客户端传过来的数据
            JSONObject nwObj = JSONObject.parseObject(newDataJSON);

            // 消息发送者的uid（必须是RainbowChat用户表中已存在的用户）
            String from = nwObj.getString("from");
            // 消息接收者的uid（必须是RainbowChat用户表中已存在的用户）
            String to = nwObj.getString("to");
            // 消息内容，是 MsgBody4Guest 类的JSON文本内容
            // 见：http://docs.52im.net/extend/docs/api/rainbowchatserver4_pro/com/x52im/rainbowchat/im/dto/MsgBody4Guest.html
            String dataContent = nwObj.getString("dataContent");
            // 0 表示false、1表示true，建议填“1”
            boolean QoS = "1".equals(nwObj.getString("QoS"));// 0 表示false、1表示true
            // 消息类型，参见：MsgBodyRoot 类中的“聊天消息类型”常量定义
            // 见：http://docs.52im.net/extend/docs/api/rainbowchatserver4_pro/com/x52im/rainbowchat/im/dto/MsgBodyRoot.html
            int typeu = CommonUtils.getIntValue(nwObj.getString("typeu"), -1);

            boolean result = false;

            // 如果是模拟客户端发送临时聊天消息则调用以下方法
            if (typeu == UserProtocalsType.MT43_OF_TEMP$CHAT$MSG_SERVER$TO$B) {
                // 以下方法是完整的RainbowChat临时聊天消息发送方式，包含了离线处理等异常情况
                result = ChatLogicManager.processMT42_OF_TEMP$CHAT$MSG_A$TO$SERVER(Protocal.genFingerPrint(), dataContent);
            }
            // 其它特权消息请根据实际情况决定是否要离线处理等特殊情况
            else {
                Protocal p = ProtocalFactory.createCommonData(dataContent
                        , from, to, QoS, Protocal.genFingerPrint(), typeu);

                // 首先判断消息接收者是否在线
                if (OnlineProcessor.isOnline(to)) {
                    // 以下方法是用于实时消息发送的
//						result = MessageHelper.sendMessage(from, to, dataContent, QoS, typeu);
//						result = LocalSendHelper.sendData(p);
                    result = true;
                }
                // 如果接收者不在线的话，特权指令的处理情况有待进一步约定
                else {
                    LoggerFactory.getLog().warn("【特权接口】向客户端" + to
                            + "推送的消息因对方不在线而不能实时发送，应针对不同" +
                            "的特权消息类型考虑离线情况下的处理哦(dataContent=" + dataContent + ")");

                    // TODO 不同类型的特权消息发送需要进一步处理哦！
                }
            }

            return result ? "1" : "0";
        }
        throw EndsExceptionFactory.INVALID_ACTION_ID(action_id);
    }
}
